package com.ebs.md.fxmonitor.orders;

/**
 * Revision Author:
 *  $File: //depot/MarketData/fxmonitor/main/src/main/java/com/ebs/md/fxmonitor/orders/OrdersNSnapshotListener.java $
 *  $Revision: #2 $
 *  $DateTime: 2012/04/22 16:07:41 $
 *  $Change: 110492 $
 *  $Author: Arik.Sher $
 */

import java.util.Collections;
import java.util.Set;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import com.ebs.commons.comp.IParsedPayload;
import com.ebs.md.api.IDetailedBookEntry;
import com.ebs.md.api.IIdentifiedOrder;
import com.ebs.md.api.ISnapshot;
import com.ebs.md.api.abs.AbsMultilpleBooksManager;
import com.ebs.md.api.order.IOrderAdapter;
import com.ebs.md.api.orderbook.ISnapshotSideAdapter;


public class OrdersNSnapshotListener
implements MessageListener
{
    final protected Logger logger = Logger.getLogger(getClass());

    final static String MQ_MSG_NAME_SNAPSHOT = "ROBM";
    
    
    private IOrderAdapter<IParsedPayload, IIdentifiedOrder>          orderAdapter;
    private ISnapshotSideAdapter<IParsedPayload, IDetailedBookEntry> snapshotSideAdapter;
	private Set<String> filterMqMessageNames;
	
	private AbsMultilpleBooksManager<IDetailedBookEntry, IIdentifiedOrder> multilpleBooksManager;
	
	
	public OrdersNSnapshotListener() {
		super();
		filterMqMessageNames = Collections.emptySet();
	}

	public void init() {
		Assert.notNull(orderAdapter,                   "'orderAdapter' cannot be null");
		Assert.notNull(snapshotSideAdapter,     "'snapshotSideAdapter' cannot be null");
		Assert.notNull(multilpleBooksManager, "'multilpleBooksManager' cannot be null");
	}
	
	public void setFilterMqMessageNames(Set<String> filterMqMessageNames) {
		this.filterMqMessageNames = filterMqMessageNames;
	}

	public void setOrderAdapter(IOrderAdapter<IParsedPayload, IIdentifiedOrder> orderAdapter) {
		this.orderAdapter = orderAdapter;
	}

	public void setSnapshotSideAdapter(ISnapshotSideAdapter<IParsedPayload, IDetailedBookEntry> snapshotSideAdapter) {
		this.snapshotSideAdapter = snapshotSideAdapter;
	}

	public void setMultilpleBooksManager(AbsMultilpleBooksManager<IDetailedBookEntry, IIdentifiedOrder> multilpleBooksManager) {
		this.multilpleBooksManager = multilpleBooksManager;
	}

	public void onMessage(Message message) {
        IParsedPayload payload = extractPayload(message);
        
        if ( payload != null ) {
            String mqMessageType  = payload.getParsedStringField("mq_msg_type");
        	
//            if ( filterMqMessageNames.contains(mqMessageType) ) {
            	if ( MQ_MSG_NAME_SNAPSHOT.equals(mqMessageType) ) {
            		// handle Snapshot
            		ISnapshot<IDetailedBookEntry> snapshot = snapshotSideAdapter.convert(payload);
            		multilpleBooksManager.resetSnapshotSide(snapshot);
            	} else {
            		// handle Order
            		IIdentifiedOrder order = orderAdapter.convert(payload);
            		
            		if ( order != null ) {
            			// 
            			multilpleBooksManager.applyOrder(order);
            		}
            	}
//            }
        }
	}

	
	
    protected IParsedPayload extractPayload(Message message) {
    	if ( message == null ) {
    		logger.error("incoming JMS Message is null!");
    	}
        IParsedPayload payload = null;

        if(message instanceof ObjectMessage) {
            ObjectMessage   objMsg  = (ObjectMessage) message;
            try {
				payload = (IParsedPayload) objMsg.getObject();
			} catch (JMSException e) {
				logger.error("failed extracting ParsedPayload from provided JMS message.", e);
			}
        } else {
        	logger.warn("expected JMS Message is not Object one. toString of it: '" + message.toString() + "'");
        }

        return payload;
    }
	
	
}
